package com.naiterui.ehp.bs.b2c.product.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.naiterui.common.repository.page.PageParamVO;
import com.naiterui.common.repository.page.PageVO;
import com.naiterui.ehp.bp.bo.b2c.ProductBoxBO;
import com.naiterui.ehp.bp.bo.b2c.ProductDefaultUsageBO;
import com.naiterui.ehp.bp.bo.b2c.ProductInventoryBO;
import com.naiterui.ehp.bp.bo.b2c.ProductSkuBO;
import com.naiterui.ehp.bp.bo.b2c.param.InventoryParamBO;
import com.naiterui.ehp.bp.bo.doctor.product.CategoryBO;
import com.naiterui.ehp.bp.bo.doctor.product.CueWordBO;
import com.naiterui.ehp.bp.bo.doctor.product.ProductDetailBO;
import com.naiterui.ehp.bp.bo.doctor.product.ProductInfoBO;
import com.naiterui.ehp.bp.bo.doctor.product.ProductSearchParamBO;
import com.naiterui.ehp.bp.utils.lang.StringUtil;
import com.naiterui.ehp.bs.b2c.common.bo.inventory.StockBO;
import com.naiterui.ehp.bs.b2c.inventory.service.IStockService;
import com.naiterui.ehp.bs.b2c.product.entity.CommonDrug;
import com.naiterui.ehp.bs.b2c.product.entity.Medicine;
import com.naiterui.ehp.bs.b2c.product.entity.Product;
import com.naiterui.ehp.bs.b2c.product.entity.Sku;
import com.naiterui.ehp.bs.b2c.product.exception.ProductBusinessException;
import com.naiterui.ehp.bs.b2c.product.repository.ICommonDrugRepository;
import com.naiterui.ehp.bs.b2c.product.repository.IProductRepository;
import com.naiterui.ehp.bs.b2c.product.repository.ISkuRepository;
import com.naiterui.ehp.bs.b2c.product.service.ICategoryService;
import com.naiterui.ehp.bs.b2c.product.service.IInnerProductService;
import com.naiterui.ehp.bs.b2c.product.service.IMedicineDefaultUsageService;
import com.naiterui.ehp.bs.b2c.product.service.IProductService;
import com.naiterui.ehp.bs.b2c.product.vo.CategoryVO;
import com.naiterui.ehp.bs.b2c.product.vo.ProductDetailVO;
import com.naiterui.ehp.bs.b2c.product.vo.ProductInfoVO;

import cn.hutool.core.bean.BeanUtil;

/**
 * @author gongbaoqiang
 * @date 2019/5/17 15:07
 * @since 1.0.0
 */
@Service
public class InnerProductServiceImpl implements IInnerProductService {

    private static final Logger LOGGER = LoggerFactory.getLogger(InnerProductServiceImpl.class);
    @Autowired
    private ISkuRepository skuRepository;
    @Autowired
    private IProductRepository productRepository;
    @Autowired
    private IStockService stockService;

    @Autowired
    private IProductService productService;
    @Autowired
    private ICategoryService categoryService;

    @Autowired
    private IMedicineDefaultUsageService medicineDefaultUsageService;
    @Autowired
    private ICommonDrugRepository commonDrugRepository;

    @Override
    public List<ProductBoxBO> getProductList(String skuIds) {
        Set<Long> ids = Arrays.asList(skuIds.split(",")).stream().map(Long::parseLong).collect(Collectors.toSet());
        List<Sku> skus = skuRepository.findAllByIdIn(ids);
        Set<Long> pids = skus.stream().map(Sku::getProductId).collect(Collectors.toSet());
        //查询sku相关主商品
        List<Product> products = productRepository.findAllByIdIn(pids);
        Map<Long, Medicine> medicineMap = productService.getMapToMedicine(pids);
        Map<Long, Product> productMap = products.stream().collect(Collectors.toMap(Product::getId, Function.identity()));
        List<ProductBoxBO> returnList = new ArrayList<>();
        skus.forEach(s -> {

            ProductBoxBO productBoxBO = new ProductBoxBO();
            BeanUtils.copyProperties(s, productBoxBO);
            Product product = productMap.get(s.getProductId());
            Medicine medicine = medicineMap.get(s.getProductId());
            BeanUtils.copyProperties(product, productBoxBO);
            productBoxBO.setName(s.getName());
            //处方合规化名称：通用名+规格
            productBoxBO.setRecomName(product.getCommonName() + " " + medicine.getSpecification());
            productBoxBO.setSale(Sku.STATUS_DOWN != s.getStatus());
            productBoxBO.setSalePrice(s.getSalePrice() == null ? "0" : s.getSalePrice() + "");
            // 商品类型
            if (product.getType() == Product.TYPE_MEDICINE) {
                productBoxBO.setDrugType(ProductBoxBO.DRUG_TYPE_TRUE);
            } else {
                productBoxBO.setDrugType(ProductBoxBO.DRUG_TYPE_FALSE);
            }
            //商品图片暂时不加
            //productBoxBO.setImage();
            //生产地址暂时不加
            //productBoxBO.setManufacturer(null);
            productBoxBO.setPrescribed(product.getNmpaType() == Product.NMPA_TYPE_RX);
            productBoxBO.setSkuId(s.getId());
            //数量单位：盒、瓶

            productBoxBO.setQuantityUnit(medicine.getPackingUnit());
            productBoxBO.setUsage(medicine.getUsageDosage());
            productBoxBO.setSpec(medicine.getSpecification());

            //todo: 下面为冗余部分，新接口可删除
            ProductSkuBO skuBO = new ProductSkuBO();
            skuBO.setSkuId(s.getId());
            skuBO.setName(s.getName());
            skuBO.setSalePrice(s.getSalePrice() == null ? "0" : s.getSalePrice() + "");
            List<ProductSkuBO> list = new ArrayList<>();
            list.add(skuBO);
            productBoxBO.setSkus(list);
            returnList.add(productBoxBO);
        });
        return returnList;
    }

    @Override
    public List<ProductInventoryBO> getInventoryInfoList(List<InventoryParamBO> goodsList) {
        Set<Long> skuIds = goodsList.stream().map(InventoryParamBO::getSkuId).collect(Collectors.toSet());
        Map<Long, Integer> numMaps =
            goodsList.stream().collect(Collectors.toMap(InventoryParamBO::getSkuId, InventoryParamBO::getNum));
        List<Sku> skus = skuRepository.findAllByIdIn(skuIds);
        // Set<String> numbers = skus.stream().map(e -> e.getNumber()).collect(Collectors.toSet());
        // 处方流转平台库存信息
        // 2021-07-20注释调用第三方库存
        // List<PlatformStockBO> platformStocks = stockService.getPlatformStocks(numbers);
        // Map<String, Long> stockNumber = platformStocks.stream().collect(Collectors.toMap(PlatformStockBO::getNumber,
        // PlatformStockBO::getInventory));

        List<StockBO> stockBOList = stockService.getStocks(skuIds);
        //库存集合
        Map<Long, StockBO> map = stockBOList.stream().collect(Collectors.toMap(StockBO::getSkuId, s -> s));
        List<ProductInventoryBO> boList = new ArrayList<>();
        //拼装InventoryBO
        skus.forEach(s -> {
            // 2021-08-30去从处方平台获取库存
            // 预警值
            // Integer inventoryWarningValue = null != s.getInventoryWarningValue() ? s.getInventoryWarningValue() : 0;
            // ProductInventoryBO bo = new ProductInventoryBO();
            // bo.setSkuId(s.getId());
            // //设置销售状态
            // bo.setSale(Sku.STATUS_UP == s.getStatus());
            // // 库存
            // // Long inventory = stockNumber.get(s.getNumber());
            // // if (inventory == null) {
            // // LOGGER.error("[库存信息]——商品库存信息不存在：skuId={}", s.getId());
            // // //设置为缺货状态
            // // bo.setShorted(ProductInventoryBO.SHORTED_YES);
            // // } else if (numMaps.get(s.getId()) != null && numMaps.get(s.getId()) > inventory) { //可适当增加库存不足的逻辑
            // // LOGGER.error("[库存信息]——请求商品数量大于库存数：skuId={},num={}, stockNum={}", s.getId(), numMaps.get(s.getId()),
            // // inventory);
            // // bo.setShorted(ProductInventoryBO.SHORTED_YES);
            // // bo.setStockNum(inventory);
            // // } else {
            // // bo.setStockNum(inventory);
            // // bo.setShorted(inventory > 0 ? ProductInventoryBO.SHORTED_NO : ProductInventoryBO.SHORTED_YES);
            // // }
            //
            // bo.setInventoryWarning(ProductInventoryBO.INVENTORY_WARNING_NO);
            // // if (null != inventory && null != numMaps.get(s.getId()) && inventory - numMaps.get(s.getId()) <
            // // inventoryWarningValue) {
            // // bo.setInventoryWarning(ProductInventoryBO.INVENTORY_WARNING_YES);
            // // bo.setStockNum(inventory);
            // // }
            // bo.setShorted(ProductInventoryBO.SHORTED_NO);
            // bo.setStockNum(9999L);
            // // 库存预警值
            // bo.setInventoryWarningValue(inventoryWarningValue);
            // boList.add(bo);
            Integer inventoryWarningValue = null != s.getInventoryWarningValue() ? s.getInventoryWarningValue() : 0;
            ProductInventoryBO bo = new ProductInventoryBO();
            bo.setSkuId(s.getId());
            //设置销售状态
            bo.setSale(Sku.STATUS_UP == s.getStatus());
            StockBO stockBO = map.get(s.getId());
            if (stockBO == null) {
                LOGGER.error("[库存信息]——商品库存信息不存在：skuId={}", s.getId());
                // 设置为缺货状态
                bo.setShorted(ProductInventoryBO.SHORTED_YES);
                bo.setStockNum(0L);
                bo.setInventoryWarning(ProductInventoryBO.INVENTORY_WARNING_YES);
            } else if (numMaps.get(s.getId()) != null && numMaps.get(s.getId()) > stockBO.getRemainQuantity()) { // 可适当增加库存不足的逻辑
                LOGGER.error("[库存信息]——请求商品数量大于库存数：skuId={},num={}, stockNum={}", s.getId(), numMaps.get(s.getId()),
                    stockBO.getRemainQuantity());
                bo.setShorted(ProductInventoryBO.SHORTED_YES);
                bo.setStockNum(stockBO.getRemainQuantity());
                bo.setInventoryWarning(ProductInventoryBO.INVENTORY_WARNING_YES);
            } else {
                bo.setStockNum(stockBO.getRemainQuantity());
                bo.setShorted(
                    stockBO.getRemainQuantity() > 0 ? ProductInventoryBO.SHORTED_NO : ProductInventoryBO.SHORTED_YES);
                bo.setInventoryWarning(bo.getStockNum() > inventoryWarningValue
                    ? ProductInventoryBO.INVENTORY_WARNING_NO : ProductInventoryBO.INVENTORY_WARNING_YES);
            }
            bo.setInventoryWarningValue(inventoryWarningValue);
            boList.add(bo);
        });
        return boList;
    }

    @Override
    public List<ProductDefaultUsageBO> getDefaultUsage(String skuIds) throws ProductBusinessException {
        return new ArrayList<>();
    }

    @Override
    public PageVO<ProductInfoBO> findProductList(ProductSearchParamBO productSearch) {
        PageVO<ProductInfoBO> page = new PageVO<>();
        List<ProductInfoBO> productList = new ArrayList<>();

        PageVO<ProductInfoVO> pageVO = productService.getProductList(new PageParamVO(productSearch.getPage(), productSearch.getNum()),
            productSearch.getCategoryId(), productSearch.getKey());
        if (pageVO == null || pageVO.getResult() == null) {
            return page;
        }

        // 校验
        List<ProductInfoVO> result = pageVO.getResult();
        if (result.isEmpty()) {
            LOGGER.info("搜索商品为空 {}", productSearch);
            return page;
        }

        // Set<String> numbers = result.stream().map(e -> e.getNumber()).collect(Collectors.toSet());
        // 处方流转平台库存信息
        // List<PlatformStockBO> platformStocks = stockService.getPlatformStocks(numbers);
        // Map<String, Long> stockNumber = platformStocks.stream().collect(Collectors.toMap(PlatformStockBO::getNumber,
        // PlatformStockBO::getInventory));

        // 商品库存
        List<StockBO> stocks =
            stockService.getStocks(result.stream().map(ProductInfoVO::getSkuId).collect(Collectors.toSet()));

        Map<Long, Long> stockNumber =
            stocks.stream().collect(Collectors.toMap(StockBO::getSkuId, StockBO::getRemainQuantity, Long::sum));

        // 查询常用药
        Long doctorId = productSearch.getDoctorId();
        List<CommonDrug> commonDrugList = commonDrugRepository.findCommonDrugByDoctorId(doctorId);
        Map<Long, Long> commonDrugMap =
            commonDrugList.stream().collect(Collectors.toMap(CommonDrug::getProductId, CommonDrug::getDoctorId));

        // 组装BO
        result.forEach(productInfoVO -> {
            ProductInfoBO productInfoBO = new ProductInfoBO();
            BeanUtils.copyProperties(productInfoVO, productInfoBO);
            productInfoBO.setSalePrice(StringUtil.formatFen2YuanStr(productInfoVO.getSalePrice()));
            Long number = stockNumber.get(productInfoVO.getSkuId());
            productInfoBO.setQuantity(number == null ? 0L : number);
            // 该药品是否已加入医生的常用药
            productInfoBO.setCommonDrug(
                (commonDrugMap != null && commonDrugMap.containsKey(productInfoVO.getProductId())) ? 1 : 0);
            // 组装BO
            productList.add(productInfoBO);
        });

        return PageVO.newBuilder().pageNo(pageVO.getPageNo()).pageSize(pageVO.getPageSize()).result(productList).totalCount(pageVO.getTotalCount())
            .offset(pageVO.getOffset()).build();
    }

    @Override
    public ProductDetailBO getProductDetail(Long skuId) throws ProductBusinessException {
        // 获取商品详情
        ProductDetailVO productDetail = productService.getProductDetail(skuId);

        if (productDetail == null) {
            LOGGER.info("获取商品详情为空 skuId:{}", skuId);
            return null;
        }

        ProductDetailBO product = new ProductDetailBO();
        BeanUtil.copyProperties(productDetail, product);
        product.setSalePrice(StringUtil.formatFen2YuanStr(productDetail.getSalePrice()));
        return product;
    }

    @Override
    public List<CueWordBO> getProductNameList(String key) {
        List<String> productList = productRepository.findByNameLike(key);
        List<CueWordBO> cueWord = new ArrayList<>();
        if (productList == null || productList.isEmpty()) {
            return cueWord;
        }
        productList.forEach(product -> cueWord.add(new CueWordBO(product)));
        return cueWord;
    }

    @Override
    public List<CategoryBO> getCategory() {
        List<CategoryBO> categoryBOS = new ArrayList<>();

        // 获取分类列表
        List<CategoryVO> categoryList = categoryService.getCategoryList();
        if (categoryList == null || categoryList.isEmpty()) {
            return categoryBOS;
        }

        // 组装BO
        categoryList.forEach(category -> {
            CategoryBO categoryBO = new CategoryBO();
            BeanUtils.copyProperties(category, categoryBO);
            categoryBOS.add(categoryBO);
        });

        return categoryBOS;
    }
}
